Skip to content

fix(ranking): rank multi-chain benches by contested-chain wins, not the mix - #2280

Merged
Flotapponnier merged 1 commit into
devfrom
fix/rank-by-contested-chain-wins
Sep 8, 2026
Merged

fix(ranking): rank multi-chain benches by contested-chain wins, not the mix#2280
Flotapponnier merged 1 commit into
devfrom
fix/rank-by-contested-chain-wins

Conversation

@Flotapponnier

Copy link
Copy Markdown
Collaborator

The bug

On a bench that declares chain dimensions, the headline ranking used the cross-chain aggregate. That aggregate is a mix, not a comparison: it rewards a provider for the chains it happens to be measured on. A provider measured on exactly one chain that nobody else reported could top the board without ever beating anyone.

Five live benches shipped that way. Measured against the staging API, all 15 chain-dimensioned live benches:

bench aggregate leader chains it is measured on most chains led
rpc-capabilities Binance 1 PublicNode, 6
wallet-labels-coverage XRPScan 1 Serialized, 4
token-quote-coverage Jupiter 1 Mobula, 2
bridge-fee Squid Router 1 Across, 1
perp-liq-rate Lighter 1 Paradex, 1

Bench 008 in detail:

provider old rank aggregate chains measured chains led
StellarExpert 1 80.08% 1 (uncontested) 0 contested
XRPScan 2 79.84% 1 (uncontested) 0 contested
Serialized 3 76.98% 5 4
Mobula 5 46.75% 8 3

stellar, xrp and bitcoin have exactly one provider measured on them.

The change

rankedCandidates sorts by contested-chain wins first, aggregate value only as a tiebreak. A chain counts toward the total only when at least two providers reported data on it, so an uncontested chain awards nothing.

Guarded by the per-chain stashes (bestPerChain, providersPerChain), which materialize/load.ts populates only on the unfiltered view. A chain-filtered variant carries neither, so ?chain=bnb keeps ranking by value exactly as before, and a bench with no chain dimensions is untouched.

providers.ts reuses the same comparator. The two surfaces disagreeing is what produced #3 of 8 sitting next to five chain-leadership chips on one row of /products/serialized.

Known trade-off

A provider with one contested win now ranks above a provider with none and a higher aggregate figure — on 008, TonAPI (35.6%, 1 win) above XRPScan (79.8%, 0 contested chains). That is what ranking on head-to-head record means, and the win count is visible on the row. The alternative considered was scoring on the mean over contested chains only, which produces no inversions but drops uncontested providers off the board entirely.

Blast radius

rankedCandidates feeds leader(), fieldValue(), /api/stat, MCP, llm-context, JSON-LD, OG images and the templated headline sentences. The published leader changes for the five benches above, and the daily Parquet snapshot's headlines table will follow from the next run.

Rule documented in /methodology, section II.

241 tests pass (4 new), typecheck clean, eslint clean on touched files, 218 specs valid.

🤖 Generated with Claude Code

…he mix

On a bench with chain dimensions the cross-chain aggregate is a mix, not a
comparison. Ranking on it alone let a provider measured on one chain that
nobody else reported finish above a provider that led several contested
ones. Five live benches shipped that way:

  rpc-capabilities        Binance 1st on 1 chain, PublicNode led 6
  wallet-labels-coverage  XRPScan 1st on 1 chain, Serialized led 4
  token-quote-coverage    Jupiter 1st on 1 chain, Mobula led 2
  bridge-fee              Squid Router 1st on 1 chain
  perp-liq-rate           Lighter 1st on 1 chain

rankedCandidates now sorts by contested-chain wins first and uses the
aggregate value only to break ties. A chain counts only when at least two
providers reported on it, so an uncontested chain awards nothing: you do
not win a race you ran alone.

Guarded by the per-chain stashes, which materialize/load.ts populates only
on the unfiltered view. A chain-filtered variant has none, so ?chain=bnb
keeps ranking by value as before.

providers.ts reuses the same ordering. The two surfaces disagreeing is what
put "#3 of 8" next to five chain-leadership chips on the same bench row.

Known and accepted: a provider with one contested win now ranks above one
with none and a higher aggregate figure (TonAPI over XRPScan on 008). That
is what ranking on head-to-head record means; the win count is on the row.

Rule documented in methodology, section II.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Flotapponnier
Flotapponnier merged commit e5950ff into dev Sep 8, 2026
1 check failed
@Flotapponnier
Flotapponnier deleted the fix/rank-by-contested-chain-wins branch September 8, 2026 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant